﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;
using BlogEngine.Core;
using System.Globalization;

namespace _4mvcBlog.Core
{
    public class BlogBaseController : BaseController
    {
        private StringBuilder _head = new StringBuilder();

        protected override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            AddGenericHeadContent();

            base.OnResultExecuting(filterContext);
        }

        /// <summary>
        /// 重写view方法，修改默认的MasterName为Blog.Master.
        /// 如果是主题预览，则修改IViewEngine
        /// </summary>
        protected override ViewResult View(string viewName, string masterName, object model)
        {
            masterName = string.IsNullOrEmpty(masterName) ? "Blog" : masterName;
            return base.View(viewName, masterName, model);
        }

        #region 添加内容到Html的head标签中(ViewData["Head"])

        /// <summary>
        /// 添加基本的link和script到HTML的header头标记中.
        /// </summary>
        public void AddGenericHeadContent()
        {
            // Links
            AddGenericLink("contents", "Archive", Utils.RelativeWebRoot + "archive.aspx");
            AddGenericLink("start", BlogSettings.Instance.Name, Utils.RelativeWebRoot);
            AddGenericLink("application/rdf+xml", "meta", "SIOC", Utils.AbsoluteWebRoot + "sioc.axd");
            AddGenericLink("application/apml+xml", "meta", "APML", Utils.AbsoluteWebRoot + "apml.axd");
            AddGenericLink("application/rdf+xml", "meta", "FOAF", Utils.AbsoluteWebRoot + "foaf.axd");

            if (string.IsNullOrEmpty(BlogSettings.Instance.AlternateFeedUrl))
            {
                AddGenericLink("application/rss+xml", "alternate", BlogSettings.Instance.Name + " (RSS)", Utils.FeedUrl + "?format=rss");
                AddGenericLink("application/atom+xml", "alternate", BlogSettings.Instance.Name + " (ATOM)", Utils.FeedUrl + "?format=atom");
            }
            else
            {
                AddGenericLink("application/rss+xml", "alternate", BlogSettings.Instance.Name, Utils.FeedUrl);
            }

            AddGenericLink("application/rsd+xml", "edituri", "RSD", Utils.AbsoluteWebRoot + "rsd.axd");

            AddMetaContentType();
            AddLocalizationKeys();

            if (BlogSettings.Instance.EnableOpenSearch)
                AddGenericLink("application/opensearchdescription+xml", "search", BlogSettings.Instance.Name, Utils.AbsoluteWebRoot + "opensearch.axd");

            if (!string.IsNullOrEmpty(BlogSettings.Instance.HtmlHeader))
                AddCustomCodeToHead();

            if (!string.IsNullOrEmpty(BlogSettings.Instance.TrackingScript))
                AddTrackingScript();


            AddJavaScriptInclude("blog.js");

            if (User.IsInRole(BlogSettings.Instance.AdministratorRole))
            {
                AddJavaScriptInclude(Utils.RelativeWebRoot + "admin/widget.js");
                AddStylesheetInclude(Utils.RelativeWebRoot + "admin/widget.css");
            }
            ViewData["Head"] = _head;
        }

        /// <summary>
        /// Adds the localization keys to JavaScript for use globally.
        /// </summary>
        private void AddLocalizationKeys()
        {
            StringBuilder sb = new StringBuilder("<script type=\"text/javascript\">");

            sb.AppendFormat("KEYhasRated='{0}';", Translate("youAlreadyRated").Replace("'", "\\'"));
            sb.AppendFormat("KEYwebRoot='{0}';", Utils.RelativeWebRoot);
            sb.AppendFormat("KEYsavingTheComment='{0}';", Translate("savingTheComment").Replace("'", "\\'"));
            sb.AppendFormat("KEYcomments='{0}';", Translate("comments").Replace("'", "\\'"));
            sb.AppendFormat("KEYcommentWasSaved='{0}';", Translate("commentWasSaved").Replace("'", "\\'"));
            sb.AppendFormat("KEYcommentWaitingModeration='{0}';", Translate("commentWaitingModeration").Replace("'", "\\'"));
            sb.AppendFormat("KEYcancel='{0}';", Translate("cancel").Replace("'", "\\'"));
            sb.AppendFormat("KEYfilter='{0}';", Translate("filter").Replace("'", "\\'"));
            sb.AppendFormat("KEYapmlDescription='{0}';", Translate("filterByApmlDescription").Replace("'", "\\'"));

            sb.Append("</script>");
            _head.Append(sb.ToString());
        }

        /// <summary>
        /// Adds the content-type meta tag to the header.
        /// </summary>
        private void AddMetaContentType()
        {
            string str = "<meta http-equiv=\"content-type\" content=\"{0}\" />";
            _head.Append(string.Format(str, HttpContext.Response.ContentType + "; charset=" + HttpContext.Response.ContentEncoding.HeaderName));
        }

        /// <summary>
        /// Add a meta tag to the page's header.
        /// </summary>
        protected void AddMetaTag(string name, string value)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value))
                return;

            string str = "<meta name=\"{0}\" contect=\"{1}\" />";
            _head.Append(string.Format(str, name, value));
        }

        /// <summary>
        /// Adds the generic link to the header.
        /// </summary>
        private void AddGenericLink(string relation, string title, string href)
        {
            string str = "<link rel=\"{0}\" title=\"{1}\" href=\"{2}\" />";
            _head.Append(string.Format(str, relation, title, href));
        }

        /// <summary>
        /// Adds the generic link to the header.
        /// </summary>
        private void AddGenericLink(string type, string relation, string title, string href)
        {
            string str = "<link type=\"{3}\" rel=\"{0}\" title=\"{1}\" href=\"{2}\" />";
            _head.Append(string.Format(str, relation, title, href, type));
        }

        /// <summary>
        /// Adds a JavaScript reference to the HTML head tag.
        /// </summary>
        private void AddJavaScriptInclude(string url)
        {
            string str = "<script type=\"text/javascript\" src=\"{0}\" ></script>";
            _head.Append(string.Format(str, ResolveScriptUrl(url)));
        }

        /// <summary>
        /// Adds a Stylesheet reference to the HTML head tag.
        /// </summary>
        /// <param name="url">The relative URL.</param>
        private void AddStylesheetInclude(string url)
        {
            string str = "<script type=\"text/css\" href=\"{0}\" rel=\"stylesheet\" ></script>";
            _head.Append(string.Format(str, url));
        }

        /// <summary>
        /// 生成JS引用URL.
        /// </summary>
        /// <param name="url">引用的JS的相对路径.</param>
        /// <returns></returns>
        private string ResolveScriptUrl(string url)
        {
            return Utils.RelativeWebRoot + "js.axd?path=" + HttpUtility.UrlEncode(url) + "&v=" + BlogSettings.Instance.Version();
        }

        /// <summary>
        /// Adds a JavaScript to the bottom of the page at runtime.    
        /// </summary>
        /// <remarks>
        /// You must add the script tags to the BlogSettings.Instance.TrackingScript.
        /// </remarks>
        private void AddTrackingScript()
        {
            StringBuilder sb = new StringBuilder("<script type=\"text/javascript\">");
            sb.Append(BlogSettings.Instance.TrackingScript);
            sb.Append("</script>");
            _head.Append(sb.ToString());
        }

        /// <summary>
        /// Adds code to the HTML head section.
        /// </summary>
        private void AddCustomCodeToHead()
        {
            _head.Append(string.Format(CultureInfo.InvariantCulture, "{0}<!-- Start custom code -->{0}{1}{0}<!-- End custom code -->{0}", Environment.NewLine, BlogSettings.Instance.HtmlHeader));
        }

        /// <summary>
        /// Translates the specified string using the resource files
        /// </summary>
        public string Translate(string text)
        {
            try
            {
                return ControllerContext.HttpContext.GetGlobalResourceObject("labels", text).ToString();
            }
            catch (NullReferenceException)
            {
                return text;
            }
        }

        #endregion

        /// <summary>
        /// 访问统计
        /// </summary>
        protected override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            if (filterContext.Result is ViewResult)
            {
                BlogEngine.Core.Counter.AddHits();
            }
            base.OnResultExecuted(filterContext);
        }
    }
}
